const PriorityQueue = require("../template")

function testPriorityQueueHeapOperations() {
  console.log(
    "1. 堆向上调整测试:",
    (() => {
      const pq = new PriorityQueue()
      
      // 插入数据触发向上调整
      pq.enqueue(10)
      pq.enqueue(5)
      pq.enqueue(15)
      pq.enqueue(3)
      pq.enqueue(8)
      
      // 验证堆性质
      return pq.isValid() === true &&
             pq.peek() === 3 && // 最小值在根节点
             pq.size() === 5
    })()
  )

  console.log(
    "2. 堆向下调整测试:",
    (() => {
      const pq = new PriorityQueue()
      
      // 插入数据
      pq.enqueue(10)
      pq.enqueue(5)
      pq.enqueue(15)
      pq.enqueue(3)
      pq.enqueue(8)
      
      // 删除元素触发向下调整
      const min1 = pq.dequeue()
      const min2 = pq.dequeue()
      
      return min1 === 3 &&
             min2 === 5 &&
             pq.peek() === 8 &&
             pq.isValid() === true &&
             pq.size() === 3
    })()
  )

  console.log(
    "3. 堆交换操作测试:",
    (() => {
      const pq = new PriorityQueue()
      
      // 插入数据
      pq.enqueue(50)
      pq.enqueue(30)
      pq.enqueue(70)
      pq.enqueue(20)
      pq.enqueue(40)
      
      // 验证堆结构
      const elements = pq.toArray()
      const isValid = pq.isValid()
      
      return isValid === true &&
             pq.peek() === 20 && // 最小值在根节点
             elements.length === 5
    })()
  )

  console.log(
    "4. 堆索引计算测试:",
    (() => {
      const pq = new PriorityQueue()
      
      // 插入数据
      pq.enqueue(10)
      pq.enqueue(20)
      pq.enqueue(30)
      pq.enqueue(40)
      pq.enqueue(50)
      
      // 验证堆结构
      const isValid = pq.isValid()
      const size = pq.size()
      
      return isValid === true &&
             size === 5 &&
             pq.peek() === 10
    })()
  )

  console.log(
    "5. 堆性质维护测试:",
    (() => {
      const pq = new PriorityQueue()
      
      // 插入大量数据
      const values = [50, 30, 70, 20, 40, 60, 80, 10, 25, 35, 45, 55, 65, 75, 85]
      values.forEach(val => pq.enqueue(val))
      
      // 验证堆性质
      const isValid = pq.isValid()
      const min = pq.peek()
      const expectedMin = Math.min(...values)
      
      return isValid === true &&
             min === expectedMin &&
             pq.size() === values.length
    })()
  )

  console.log(
    "6. 堆重建测试:",
    (() => {
      const pq = new PriorityQueue()
      
      // 插入数据
      const values = [50, 30, 70, 20, 40, 60, 80]
      values.forEach(val => pq.enqueue(val))
      
      // 删除一些元素
      pq.dequeue()
      pq.dequeue()
      pq.dequeue()
      
      // 验证堆仍然有效
      const isValid = pq.isValid()
      const remainingMin = pq.peek()
      
      return isValid === true &&
             remainingMin === 50 && // 剩余的最小值
             pq.size() === 4
    })()
  )

  console.log(
    "7. 堆边界条件测试:",
    (() => {
      const pq = new PriorityQueue()
      
      // 测试单元素堆
      pq.enqueue(42)
      const isValid1 = pq.isValid()
      const peek1 = pq.peek()
      
      // 测试两元素堆
      pq.enqueue(21)
      const isValid2 = pq.isValid()
      const peek2 = pq.peek()
      
      return isValid1 === true &&
             peek1 === 42 &&
             isValid2 === true &&
             peek2 === 21 &&
             pq.size() === 2
    })()
  )

  console.log(
    "8. 堆性能测试:",
    (() => {
      const pq = new PriorityQueue()
      const iterations = 1000
      
      const start = performance.now()
      
      // 插入大量数据
      for (let i = 0; i < iterations; i++) {
        pq.enqueue(i)
      }
      
      // 删除所有数据
      for (let i = 0; i < iterations; i++) {
        pq.dequeue()
      }
      
      const end = performance.now()
      const duration = end - start
      
      return pq.size() === 0 &&
             pq.isEmpty() === true &&
             duration < 1000 && // 应该在1秒内完成
             duration > 0
    })()
  )

  console.log(
    "9. this上下文堆操作测试:",
    (() => {
      const heapObj = {
        multiplier: 2,
        processHeapOperations: function(values) {
          const pq = new PriorityQueue()
          values.forEach(val => pq.enqueue(val))
          return pq.size() * this.multiplier
        }
      }
      
      const values = [10, 20, 30, 40, 50]
      return heapObj.processHeapOperations(values) === 10 // 5*2=10
    })()
  )

  console.log(
    "10. 复杂对象this绑定堆操作测试:",
    (() => {
      const heapConfigObj = {
        config: { threshold: 3 },
        processWithConfig: function(values) {
          const pq = new PriorityQueue()
          values.forEach(val => pq.enqueue(val))
          return pq.size() >= this.config.threshold
        }
      }
      
      const values = [10, 20, 30]
      return heapConfigObj.processWithConfig(values) === true
    })()
  )

  console.log(
    "11. 堆一致性测试:",
    (() => {
      const pq = new PriorityQueue()
      
      // 插入数据
      const values = [50, 30, 70, 20, 40, 60, 80]
      values.forEach(val => pq.enqueue(val))
      
      // 验证堆性质
      const isValid1 = pq.isValid()
      const min1 = pq.peek()
      
      // 删除元素
      pq.dequeue()
      
      // 再次验证堆性质
      const isValid2 = pq.isValid()
      const min2 = pq.peek()
      
      return isValid1 === true &&
             min1 === 20 &&
             isValid2 === true &&
             min2 === 30 &&
             pq.size() === 6
    })()
  )

  console.log(
    "12. 堆复杂操作测试:",
    (() => {
      const pq = new PriorityQueue()
      
      // 复杂插入序列
      const complexValues = [50, 30, 70, 20, 40, 60, 80, 10, 25, 35, 45, 55, 65, 75, 85]
      complexValues.forEach(val => pq.enqueue(val))
      
      // 验证堆性质
      const isValid = pq.isValid()
      const min = pq.peek()
      const max = Math.max(...complexValues)
      
      // 删除一些元素
      pq.dequeue()
      pq.dequeue()
      pq.dequeue()
      
      // 再次验证
      const isValidAfter = pq.isValid()
      const remainingMin = pq.peek()
      
      return isValid === true &&
             min === 10 &&
             isValidAfter === true &&
             remainingMin === 20 &&
             pq.size() === 12
    })()
  )
}

testPriorityQueueHeapOperations()
